package com.nx.platform.es.biz.esspider.handler;

import com.nx.platform.es.biz.esspider.resource.DBManager;
import com.nx.platform.es.biz.esspider.entity.Item;
import com.nx.platform.es.common.utils.MoreMaps;
import org.apache.commons.collections4.MapUtils;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 提供一对多处理能力：sum，max，min，avg，multi
 *
 * @author wangjianying
 * @since Aug 19, 2019
 */
@HandlerDefine(HandlerType.DB)
public class DBGroupByPrimaryIdHandler extends AbstractDBGroupByHandler {

    public DBGroupByPrimaryIdHandler(String identity, DBManager dbManager) {
        super(identity, dbManager);
    }

    @Override
    public void handle(Map<Long, Item> items) throws Exception {
        if (items.isEmpty()) {
            return;
        }
        // 查询数据库
        SqlParameterSource queryParams;
        if (toString) {
            queryParams = new MapSqlParameterSource(SQL_IDS_KEY,
                    items.keySet().stream().map(String::valueOf).collect(Collectors.toList()));
        } else {
            queryParams = new MapSqlParameterSource(SQL_IDS_KEY, items.keySet());
        }
        List<Map<String, Object>> queryResults = getJdbcTemplate().queryForList(sql, queryParams);
        if (queryResults.isEmpty()) {
            return;
        }
        // 查询结果进一步处理
        Map<Long, Map<Object, Collection<Object>>> fieldValuesMap = new HashMap<>(queryResults.size());
        queryResults.forEach((Map<String, Object> queryResult) -> {
            Long idFieldValue = MoreMaps.getLong(queryResult, idField);
            if (idFieldValue == null) {
                return;
            }
            Map<Object, Collection<Object>> valuesMap = fieldValuesMap.computeIfAbsent(idFieldValue, (k) -> new HashMap<>());
            fields.values().stream().flatMap(Set::stream).forEach(fieldKey -> {
                Collection<Object> values = valuesMap.computeIfAbsent(fieldKey, (k) -> new LinkedList<>());
                Object fieldValue = MoreMaps.getObject(queryResult, fieldKey);
                values.add(fieldValue);
            });
        });
        // 更新文档数据
        for (Map.Entry<Long, Item> e : items.entrySet()) {
            Map<Object, Collection<Object>> valuesMap = fieldValuesMap.get(e.getKey());
            if (MapUtils.isNotEmpty(valuesMap)) {
                fields.forEach((key, value) -> {
                    for (String s : value) {
                        Collection<Object> values = valuesMap.getOrDefault(s, Collections.emptySet());
                        e.getValue().getDoc().putIfAbsent(s, key.parse(values));
                    }
                });
            }
        }
    }
}